<?php
class prodstock {
  private $legal_state = array( 0=>'Старт', 2=>'Процес', 6=>'Финиш', 14=>'Готово' );
  
  function __construct() {
  }

  public function select() {
    $data = new jqGridData();
    try
    {
// Только зарегистрированные пользователи могут видеть данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

		$rwd = $_SESSION['priv']->prodstock->rwd;
		if( !$rwd  ) throw new Exception(ERR_M::DATA_ACC_DISABLED, 99);

// Проверяем данные
        $page    = ( isset($_REQUEST["page"]) && $_REQUEST["page"] > 0 ) ? $_REQUEST["page"] : 1;
        $limit    = ( isset($_REQUEST["rows"]) && $_REQUEST["rows"] > 0 ) ? $_REQUEST["rows"] : 1;
        $sidx    = ( isset($_REQUEST["sidx"]) && $_REQUEST["sidx"] != '' ) ? $_REQUEST["sidx"] : 'prod_start';
        $sord    = ( isset($_REQUEST["sord"]) && strtolower($_REQUEST["sord"]) == 'desc' ) ? 'DESC' : 'ASC';
        $search    = ( isset($_REQUEST["_search"]) && strtolower($_REQUEST["_search"]) == 'true') ? true : false;
 
// Открываем базу данных
		$db = App::me()->dbOpen();	
		
// Фильтр
        $whc = array();
		
        if( $search )
        {
            if(isset($_REQUEST["id"]) && ctype_digit($_REQUEST["id"]) ) {
				$whc[] = "prs_id=" . $db->quote($_REQUEST["prs_id"]);
		    }
            
            if(isset($_REQUEST["art_code"]) && $_REQUEST["art_code"] != "") {
				$whc[] = "art_code LIKE " . $db->quote("%".$_REQUEST["art_code"]."%");
            }
			
            if(isset($_REQUEST["art_full_name"]) && $_REQUEST["art_full_name"] != "") {
		    	$whc[] = "art_full_name LIKE " . $db->quote("%".$_REQUEST["art_full_name"]."%");
            }
		}

// Фильтр привилегий
		if( $rwd & PERM_BITS::READ_OTH ) $whc[] = '1 = 1';
		elseif( $rwd & PERM_BITS::READ_GRP ) 
			$whc[] = 'prs_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::READ_OWN ) $whc[] = 'prs_user_id = '.$_SESSION['user_id'];
		else $whc[] = '1 = 0';

// Окончательно формируем условие
        $whereclaus = (count($whc) != 0 ) ? " WHERE " . implode(" AND ", $whc) : "";
		unset($whc);
            
// Получаем количество записей с учетом фильтра
        $join1 = " INNER JOIN articles ON art_id=prs_art_id ";
		$join2 = " LEFT JOIN metrics ON met_id = art_met_id ";
			
        $sql = "SELECT COUNT(*) AS count FROM prodstock ".$join1.$whereclaus;
        $rs = $db->query( $sql );
		$count = $rs->fetchObject()->count;
		$rs->closeCursor();
            
// Пустая таблица
        if ($count == 0)
			throw new Exception(ERR_M::SUCCESS, 0);
            
// Рассчитаем сколько всего страниц займут данные в БД
    	if( $count > 0 && $limit > 0) {
    		$total_pages = ceil($count/$limit);
    	} else {
    		$total_pages = 0;
    	}                  
 
		if ($page > $total_pages) $page=$total_pages;                  
 
		$start = $limit*$page - $limit;                   
		if($start < 0) $start = 0;                  
 
// Формируем запрос
		$sql = 	"SELECT prs_id,prs_art_id,art_code,art_full_name,prs_amount,met_name,prs_comment ".
				"FROM prodstock ".$join1.$join2.$whereclaus." ORDER BY ".$sidx." ".$sord.
		        " LIMIT ".$start.", ".$limit;

		$rs = $db->query($sql);                  
 
// Формирование объекта для возврата
        
    	$data->page      = $page;
    	$data->total     = $total_pages;
    	$data->records   = $count;
    		
    // Строки данных для таблицы
		$i = 0;
		while( $row = $rs->fetchObject() ) {			
			$data->rows[$i]['id'] = $row->prs_id;
			$data->rows[$i]['cell'] = array(
					$row->prs_id,
					$row->prs_art_id,
					$row->art_code,
					$row->art_full_name,
					$row->prs_amount,
					$row->met_name,
					$row->prs_comment
		    );
		    $i++;
		}
    }
	catch (PDOException $e) {
		$data->userdata->errcode = 1;
		$data->userdata->errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$data->userdata->errcode = $e->getCode();
		$data->userdata->errmess = $e->getMessage();
	}
 
	return $data;
  }
  
  
  public function insert() {

    $prs_art_id	= isset($_POST['prs_art_id']) ? trim(strip_tags($_POST['prs_art_id'])) : '';
    $art_code		= isset($_POST['art_code']) ? trim(strip_tags($_POST['art_code'])) : '';
    $prs_amount		= isset($_POST['prs_amount']) ? trim(strip_tags($_POST['prs_amount'])) : '';
    $prs_comment	= isset($_POST['prs_comment']) ? trim(strip_tags($_POST['prs_comment'])) : '';
	
	$errcode = 0;
	$errmess = '';
	
    try
    {
// Только зарегистрированные пользователи могут вносить данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);
		$prs_user_id = $spr_user_id = $_SESSION['user_id'];
		
//Есть ли разрешение на вставку записей
		$rwd = $_SESSION['priv']->prodstock->rwd;
		if( !$rwd & PERM_BITS::WRITE_OWN ) 
			throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);

// Все ли данные переданы
		$errdata = "";
		
// Открываем базу данных
		$db = App::me()->dbOpen();
		
// art_code & prs_art_id
		if( !$art_code ) $errdata .= ($errdata?'<br>':'')."- Не указан шифр изделия.";
		elseif( !$prs_art_id || !ctype_digit( $prs_art_id ) ) 
			$errdata .= ($errdata?'<br>':'').'- Не указан идентификатор изделия.';
		else {
// Считываем данные из справочника
			$sql =	'SELECT art_code FROM articles WHERE art_id = '.$db->quote($prs_art_id);
			$rs = $db->query($sql);                  
			$row = $rs->fetchObject();
			if( !$row || $row->art_code != $art_code) {
				$errdata .= ($errdata?'<br>':'').'- Неправильно указан идентификатор изделия.';
			}
			$rs->closeCursor();
		}
		
// prs_amount
		if( $prs_amount === '' )
			$errdata .= ($errdata?'<br>':'').'- Не указано количество изделий.';
		else {
			$prs_amount = str_replace(',', '.', $prs_amount);
			if( !is_numeric( $prs_amount ) || $prs_amount < 0 )
				$errdata .= ($errdata?'<br>':'')."- Неправильно указано количество изделий.";
		}
		
//				
// Если есть ошибки - можно уже закончить
//
		if( $errdata ) throw new Exception($errdata, 1);
		
// Проверка существования этого артикля на складе
		$sql =	'SELECT 1 FROM prodstock WHERE prs_art_id = '.$db->quote($prs_art_id);
		$rs = $db->query($sql);                  
		$row = $rs->fetchObject();
		if( $row )
			throw new Exception('Наскладе уже есть такая категория изделий.', 1);
		$rs->closeCursor();
		
// Пишем данные
		$sql =	'INSERT prodstock SET '.
					'prs_art_id = '.$db->quote($prs_art_id).", ".
					'prs_amount = '.$db->quote($prs_amount).", ".
					'prs_comment = '.$db->quote($prs_comment).", ".
					'prs_user_id = '.$db->quote($prs_user_id);
							
		$db->exec($sql);
    }
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }

  
  public function update() {

    $prs_id			= isset($_POST['id']) ? trim(strip_tags($_POST['id'])) : '';
    $prs_art_id		= isset($_POST['prs_art_id']) ? trim(strip_tags($_POST['prs_art_id'])) : '';
    $art_code		= isset($_POST['art_code']) ? trim(strip_tags($_POST['art_code'])) : '';
    $prs_amount		= isset($_POST['prs_amount']) ? trim(strip_tags($_POST['prs_amount'])) : '';
    $prs_comment	= isset($_POST['prs_comment']) ? trim(strip_tags($_POST['prs_comment'])) : '';
	
	$errcode = 0;
	$errmess = '';
	
    try
    {
// Только зарегистрированные пользователи могут вносить данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);
		$prs_user_id = $_SESSION['user_id'];
		
//Есть ли разрешение на изменение записей
		$rwd = $_SESSION['priv']->prodstock->rwd;
		if( ($rwd & PERM_BITS::WRITE_ANY) == 0 ) throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);

// Все ли данные переданы
		$errdata = "";
		
// prs_id
        if (!$prs_id || !ctype_digit( $prs_id ))
			throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
        
// Открываем базу данных
		$db = App::me()->dbOpen();
		
// Есть ли разрешение на апдейт этой записи
		if( $rwd & PERM_BITS::WRITE_OTH ) $where = '1 = 1';
		elseif( $rwd & PERM_BITS::WRITE_GRP ) 
			$where = 'prs_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::WRITE_OWN ) $where = 'prs_user_id = '.$_SESSION['user_id'];
		else $where = '1 = 0';
		$where .= ' AND prs_id = '.$db->quote($prs_id);
		
		$sql = 'SELECT 1 FROM prodstock WHERE '.$where.' LIMIT 1';
		$rs = $db->query( $sql );		
		if( ! $rs->fetchObject() )
			throw new Exception(ERR_M::DATA_OWNER_DISABLED, 99);
		$rs->closeCursor();
		
// art_code & prs_art_id
		if( !$art_code ) $errdata .= ($errdata?'<br>':'')."- Не указан шифр изделия.";
		elseif( !$prs_art_id || !ctype_digit( $prs_art_id ) ) 
			$errdata .= ($errdata?'<br>':'').'- Не указан идентификатор изделия.';
		else {
// Считываем данные из справочника
			$sql =	'SELECT art_code FROM articles WHERE art_id = '.$db->quote($prs_art_id);
			$rs = $db->query($sql);                  
			$row = $rs->fetchObject();
			if( !$row || $row->art_code != $art_code) {
				$errdata .= ($errdata?'<br>':'').'- Неправильно указан идентификатор изделия.';
			}
			$rs->closeCursor();
		}
		
// prs_amount
		if( $prs_amount === '' )
			$errdata .= ($errdata?'<br>':'').'- Не указано количество изделий.';
		else {
			$prs_amount = str_replace(',', '.', $prs_amount);
			if( !is_numeric( $prs_amount ) || $prs_amount < 0 )
				$errdata .= ($errdata?'<br>':'')."- Неправильно указано количество изделий.";
		}		
//				
// Если есть ошибки - можно уже закончить
//
		if( $errdata ) throw new Exception($errdata, 1);
		
// Пишем данные
		$sql =	'UPDATE prodstock SET '.
					'prs_art_id = '.$db->quote($prs_art_id).", ".
					'prs_amount = '.$db->quote($prs_amount).", ".
					'prs_comment = '.$db->quote($prs_comment)." ".
				'WHERE prs_id = '.$db->quote($prs_id);
		
		$db->exec($sql);
    }
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }

  
  public function delete() {
    $errmess = "";
	$errcode = 0;
		
    $prs_ids = (isset($_REQUEST['id']) && $_REQUEST['id'] != '') ?
        explode(",", $_REQUEST["id"], 100) : array();


    try
    {
// Только зарегистрированные пользователи могут удалять данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

		$rwd = $_SESSION['priv']->prodstock->rwd;
		
        if (!Tools::is_numeric_array( $prs_ids ))
			throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
        
		$prs_id_list = implode(',', $prs_ids);

// Открываем базу данных
		$db = App::me()->dbOpen();	

// Есть ли разрешение на удаление записей prodstock.
// Заодно составим список артиклей
		if( $rwd & PERM_BITS::DELETE_OTH ) $where = '1 = 1';
		elseif( $rwd & PERM_BITS::DELETE_GRP ) 
			$where = 'prs_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::DELETE_OWN ) $where = 'prs_user_id = '.$_SESSION['user_id'];
		else $where = '1 = 0';
		$where .= ' AND prs_id IN ('.$prs_id_list.')';
		
		$art_ids = array();
		$rs = $db->query( "SELECT prs_art_id FROM prodstock WHERE ${where}" );		
		while( $row = $rs->fetchObject() ) {
			$art_ids[] = $row->prs_art_id;
		}
		if( count( $art_ids ) != count($prs_ids) )
			throw new Exception(ERR_M::DATA_OWNER_DISABLED, 99);
			
		$rs->closeCursor();
		$art_id_list = implode(',', $art_ids);

// Возможно на производстве уже есть готовая к отправке на склад продукция
		$sql =  "SELECT COUNT(*) AS count FROM products ".
				"WHERE prod_art_id IN ( ${art_id_list} ) AND prod_finish IS NOT NULL";
		$rs = $db->query( $sql );		
		$row = $rs->fetchObject();
		if( $row->count ) {
			$num = $row->count;
			throw new Exception("На производстве уже есть готовая к отправке на склад ".
								"продукция по ${num} из удаляемых позиций.",1);
		}
		$rs->closeCursor();

// Удаляем записи
		$db->exec( "DELETE FROM prodstock WHERE prs_id IN ( ${prs_id_list} )" );
	}
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }

  public function prodlist() {
	$errcode = 0;
	$errmess = '';
    $data = array();
	
    try
    {
// Только зарегистрированные пользователи могут видеть данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

// Find - услуга общего пользования. Поэтому, маска должна быть READ_ANY
		$rwd = $_SESSION['priv']->prodstock->rwd;

// Открываем базу данных
		$db = App::me()->dbOpen();	

// Фильтр привилегий
		if( $rwd & PERM_BITS::READ_OTH ) $whs = '1 = 1';
		elseif( $rwd & PERM_BITS::READ_GRP ) 
			$whs = 'prs_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::READ_OWN ) $whs = 'prs_user_id = '.$_SESSION['user_id'];
		else $whs = '1 = 0';
		
// Формируем запрос
		$sql =  "SELECT prs_id, prs_amount, art_code, art_full_name, met_name, prs_comment FROM prodstock ".
				"INNER JOIN articles ON art_id = prs_art_id ".
				"LEFT JOIN metrics ON met_id = art_met_id ".
				"WHERE ${whs} ORDER BY art_code";
		$rs = $db->query($sql);                  
        while( $row = $rs->fetchObject() ) {
            $unit = new stdClass;
            $unit->key = $row->prs_id;
			$unit->title = $row->art_code;
			$unit->exist = $row->prs_amount;
			$unit->met_name = $row->met_name;
			$unit->description = $row->art_full_name;
			$unit->comment = $row->prs_comment;
            $unit->isFolder = false;
            $unit->isLazy = false;
            $data[] = $unit;
        }
        $rs->closeCursor();
 
    }
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	if( $errcode ) {
		$unit = new stdClass;
		$unit->title = '';
		$unit->errcode = $errcode;
		$unit->errmess = $errmess;
		return array($unit);
	}
	else return $data;
  }

  public function invshiprep() {
    $data = new stdClass;
	$data->errcode = 0;
	$data->errmess = '';
	$data->prs = array();
	
    $ids	= isset($_POST['ids']) ? $_POST['ids'] : '';
    $art_code	= isset($_POST['art_code']) ? $_POST['art_code'] : '';
    $art_full_name	= isset($_POST['art_full_name']) ? $_POST['art_full_name'] : '';
    $prs_need	= isset($_POST['prs_need']) ? $_POST['prs_need'] : '';
    $met_name	= isset($_POST['met_name']) ? $_POST['met_name'] : '';
    $prs_comment	= isset($_POST['prs_comment']) ? $_POST['prs_comment'] : '';

    try
    {
// Только зарегистрированные пользователи могут видеть данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

// Проверяем данные
		if( !$ids || !$art_code  || !$art_full_name || !$prs_need || !$met_name || !$prs_comment )
			throw new Exception(ERR_M::PROTOCOL_ERROR, 1);

// Формируем массив данных для отображения
		for( $i=0; $i<count($ids); $i++ ) {
			$data->prs[$i] = new stdClass;
			$data->prs[$i]->id = $ids[$i];
			$data->prs[$i]->art_code = $art_code[$i];
			$data->prs[$i]->art_name = $art_full_name[$i];
			$data->prs[$i]->prs_need = $prs_need[$i];
			$data->prs[$i]->met_name = $met_name[$i];
			$data->prs[$i]->prs_comment = $prs_comment[$i];			
		}
		
		$data->inv_num = isset( $_POST['invnm']) ? trim(strip_tags($_POST['invnm'])) : '';
		$data->inv_date = isset( $_POST['invdt']) ? trim(strip_tags($_POST['invdt'])) : '';
		$data->from = isset( $_POST['invfr']) ? trim(strip_tags($_POST['invfr'])) : '';
		$data->rcpt = isset( $_POST['invrc']) ? trim(strip_tags($_POST['invrc'])) : '';
		$data->tdate = isset( $_POST['invtd']) ? trim(strip_tags($_POST['invtd'])) : '';
		$data->tnum = isset( $_POST['invtn']) ? trim(strip_tags($_POST['invtn'])) : '';
		$data->fpers = isset( $_POST['invfp']) ? trim(strip_tags($_POST['invfp'])) : '';
		$data->rpers = isset( $_POST['invrp']) ? trim(strip_tags($_POST['invrp'])) : '';
		
		if( !$data->inv_num || !$data->inv_date || !$data->from || !$data->rcpt ) 
			throw new Exception("Поля: 'Номер','Дата','Поставщик','Получатель' обязательны для заполнения.",1);
		
    }
    catch ( Exception $e ) {
		$data->errcode = $e->getCode();
		$data->errmess = $e->getMessage();
	}

	return $data;
  }

  
  public function delivery() {

    $inv_num	= isset($_POST['inv_num']) ? trim(strip_tags($_POST['inv_num'])) : '';
    $inv_date	= isset($_POST['inv_date']) ? trim(strip_tags($_POST['inv_date'])) : '';
    $prs	= isset($_POST['prs']) ? $_POST['prs'] : '';
	
	$errcode = 0;
	$errmess = '';
	$eps = 1E-10;
	
    try
    {
// Только зарегистрированные пользователи могут вносить данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);
		$user_id = $_SESSION['user_id'];
		
//Есть ли разрешение на изменение записей
		$rwd = $_SESSION['priv']->prodstock->rwd;

// Все ли данные переданы
		$errdata = '';
		
// inv_num
		if( !$inv_num ) $errdata .= ($errdata?'<br>':'')."- Не указан номер накладной.";

// inv_date
		if( !$inv_date ) $errdata .= ($errdata?'<br>':'')."- Не указана дата накладной.";
		elseif( ( $inv_date = Tools::check_date($inv_date ) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата накладной указана неправильно.";
// prs
		if( !is_array($prs) || !count( $prs ) ) 
			$errdata .= ($errdata?'<br>':'')."- Не сформирован 'Список изделий для отгрузки'.";
//				
// Если есть ошибки - можно уже закончить
//
		if( $errdata ) throw new Exception($errdata, 1);
		
		$ids = array();
		$need = array();
		foreach( $prs as $p ) {
			$ids[] = $p['id'];
			$need[] = $p['value'];
		}
		
        if (!Tools::is_numeric_array( $ids ) || !Tools::is_numeric_array( $need ))
			throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
        
		$prs_id_list = implode(',', $ids);
		
// Открываем базу данных
		$db = App::me()->dbOpen();
		
// Есть ли разрешение на апдейт записей в prodstock
// Заодно составим массив для дешифрации нехватки изделий на складе
		if( $rwd & PERM_BITS::WRITE_OTH ) $where = '1 = 1';
		elseif( $rwd & PERM_BITS::WRITE_GRP ) 
			$where = 'prs_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::WRITE_OWN ) $where = 'prs_user_id = '.$_SESSION['user_id'];
		else $where = '1 = 0';
		$where .= ' AND prs_id IN ('.$prs_id_list.')';
		
		$sql =	"SELECT prs_id, art_code FROM prodstock ".
				"INNER JOIN articles ON art_id=prs_art_id ".
				"WHERE ${where}";
				
		$rs = $db->query( $sql );
		
		$prs_id = array();
		$art_code = array();
		while( $row = $rs->fetchObject() ) {
			$prs_id[] = $row->prs_id;
			$art_code[] = $row->art_code;
		}
		$rs->closeCursor();
		
		if( count($prs_id) != count($ids) )
			throw new Exception("Недостаточно прав на одну или несколько записей в таблице 'Склад готовой продукции'.", 1);
		
		$artcodes = array_combine( $prs_id, $art_code );
		
		// Компилим SQL
		$sel_prs =	$db->prepare('SELECT prs_amount FROM prodstock WHERE prs_id = :prs_id FOR UPDATE');
		$upd_prs = 	$db->prepare('UPDATE prodstock SET prs_amount = :prs_amount WHERE prs_id = :prs_id');

		// Начинаем цикл списаний. Если хотя бы для одной позиции списание выполнить невозможно -
		// вся операция должна быть отменена. 

		$errdata = '';
		try {
			$db->beginTransaction();
			
			for( $i=0; $i<count($ids); $i++ ) {
				$sel_prs->execute( array( ':prs_id'=>$ids[$i] ) );
				$prs_amount = $sel_prs->fetchObject()->prs_amount;
				
				if( $prs_amount + $eps < $need[$i] )
					throw new Exception("На складе нет достаточного количества изделий по коду ".$artcodes[$ids[$i]], 1);
					
				$rs->closeCursor();

				// Делаем списание
				$prs_amount -= $need[$i];
				
				$upd_prs->execute( array( ':prs_id'=>$ids[$i], ':prs_amount'=>$prs_amount ) );
			}
			$db->commit();
		}
		catch (PDOException $e) {
			$db->rollback(); 
			$errcode = 1;
			$errmess = ERR_M::DATABASE_ERROR;
		}		
		catch ( Exception $e ) {
			$db->rollback(); 
			$errcode = $e->getCode();
			$errmess = $e->getMessage();
		}
    }
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }

  
  public function listin() {
    $data = new jqGridData();
    try
    {
// Только зарегистрированные пользователи могут видеть данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

		$rwd = $_SESSION['priv']->products->rwd;
		if( !$rwd  ) throw new Exception(ERR_M::DATA_ACC_DISABLED, 99);

// Проверяем данные
        $page   = ( isset($_REQUEST["page"]) && $_REQUEST["page"] > 0 ) ? $_REQUEST["page"] : 1;
        $limit  = ( isset($_REQUEST["rows"]) && $_REQUEST["rows"] > 0 ) ? $_REQUEST["rows"] : 1;
        $sidx   = ( isset($_REQUEST["sidx"]) && $_REQUEST["sidx"] != '' ) ? $_REQUEST["sidx"] : 'prod_tostock';
        $sord   = ( isset($_REQUEST["sord"]) && strtolower($_REQUEST["sord"]) == 'desc' ) ? 'DESC' : 'ASC';
        $search	= ( isset($_REQUEST["_search"]) && strtolower($_REQUEST["_search"]) == 'true') ? true : false;
		$art_id = isset($_POST['art_id']) ? trim(strip_tags($_POST['art_id'])) : '';
 
		if( !$art_id || !ctype_digit($art_id) )
			throw new Exception(ERR::PROTOCOL_ERROR, 1);

// Открываем базу данных
		$db = App::me()->dbOpen();	

// Фильтр
        $whc = array();
		$whc[] = 'prod_tostock IS NOT NULL';
		$whc[] = 'prod_art_id = '.$art_id;
		
        if( $search )
        {
            if(isset($_REQUEST["id"]) && ctype_digit($_REQUEST["id"]) ) {
				$whc[] = "prod_id=" . $db->quote($_REQUEST["prod_id"]);
		    }
            
            if(isset($_REQUEST["prod_tostock"]) && ( $dt = Tools::date_to_search_str( $_REQUEST["prod_tostock"] )) != "") {
				$whc[] = "prod_tostock LIKE " . $db->quote("%".$dt."%");
            }
		}

// Фильтр привилегий
		if( $rwd & PERM_BITS::READ_OTH ) $whc[] = '1 = 1';
		elseif( $rwd & PERM_BITS::READ_GRP ) 
			$whc[] = 'prod_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::READ_OWN ) $whc[] = 'prod_user_id = '.$_SESSION['user_id'];
		else $whc[] = '1 = 0';

// Окончательно формируем условие
        $whereclaus = " WHERE " . implode(" AND ", $whc);
		unset($whc);
            
// Получаем количество записей с учетом фильтра
        $join1 = " INNER JOIN articles AS art ON art_id = prod_art_id ";
		$join2 = " LEFT JOIN metrics ON met_id = art_met_id ";
			
        $rs = $db->query( "SELECT COUNT(*) AS count FROM products ".$whereclaus );
		$count = $rs->fetchObject()->count;
		$rs->closeCursor();
            
// Пустая таблица
        if ($count == 0)
			throw new Exception(ERR_M::SUCCESS, 0);
            
// Рассчитаем сколько всего страниц займут данные в БД
    	if( $count > 0 && $limit > 0) {
    		$total_pages = ceil($count/$limit);
    	} else {
    		$total_pages = 0;
    	}                  
 
		if ($page > $total_pages) $page=$total_pages;                  
 
		$start = $limit*$page - $limit;                   
		if($start < 0) $start = 0;                  
 
// Формируем запрос
		$sql = 	"SELECT prod_id, prod_tostock, prod_num, met_name ".
				"FROM products ".$join1.$join2.$whereclaus." ORDER BY ".$sidx." ".$sord.
		        " LIMIT ".$start.", ".$limit;

		$rs = $db->query($sql);                  
 
// Формирование объекта для возврата
        
    	$data->page      = $page;
    	$data->total     = $total_pages;
    	$data->records   = $count;
    		
    // Строки данных для таблицы
		$i = 0;
		while($row = $rs->fetch(PDO::FETCH_ASSOC)) {
			$data->rows[$i]['id'] = $row['prod_id'];
			$data->rows[$i]['cell'] = array(
					$row['prod_id'],
					Tools::str_iso2local_date( $row['prod_tostock'] ),
					$row['prod_num'],
					$row['met_name'],
		    );
		    $i++;
		}
    }
	catch (PDOException $e) {
		$data->userdata->errcode = 1;
		$data->userdata->errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$data->userdata->errcode = $e->getCode();
		$data->userdata->errmess = $e->getMessage();
	}
 
	return $data;
  }
  
} // End od ProdStock class
?>